package com.fastjars.business.shiro.web;

import com.fastjars.business.spring.ContextHolder;
import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.springframework.util.CollectionUtils;

import java.util.Map;

/**
 * FilterChain
 *
 * @author Brant Liu <br> 邮箱：<br>lbf1988@qq.com <br>日期：<br>2018/03/22
 * @version 1.0.0
 */
public class FilterChain {
    /**
     * 获取ShiroFilterFactoryBean对象
     */
    private ShiroFilterFactoryBean shiroFilterFactoryBean = ShiroFilterFactoryBean.me();

    /**
     * 获取当前Bean对象
     * @return
     */
    public static FilterChain me(){
        return ContextHolder.getBean(FilterChain.class);
    }

    /**
     * 重新初始化Shiro过滤链
     */
    public void reloadFilterChains(){
        // TODO: 强制同步，控制线程安全
        synchronized (shiroFilterFactoryBean){
            AbstractShiroFilter shiroFilter = null;

            try {
                shiroFilter = (AbstractShiroFilter) shiroFilterFactoryBean.getObject();

                PathMatchingFilterChainResolver resolver = (PathMatchingFilterChainResolver) shiroFilter.getFilterChainResolver();
                // 过滤管理器
                DefaultFilterChainManager manager = (DefaultFilterChainManager) resolver.getFilterChainManager();
                // 清除权限配置
                manager.getFilterChains().clear();
                shiroFilterFactoryBean.getFilterChainDefinitionMap().clear();
                // 重新设置权限
                shiroFilterFactoryBean.setFilterChainDefinitions(ShiroFilterFactoryBean.definition);//传入配置中的filterchains

                Map<String, String> chains = shiroFilterFactoryBean.getFilterChainDefinitionMap();
                //重新生成过滤链
                if (!CollectionUtils.isEmpty(chains)) {
                    chains.forEach((url, definitionChains) -> {
                        manager.createChain(url, definitionChains.trim().replace(" ", ""));
                    });
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
